home *** CD-ROM | disk | FTP | other *** search
/ EnigmA Amiga Run 1997 February / EnigmA AMIGA RUN 15 (1997)(G.R. Edizioni)(IT)[!][issue 1997-02][PLANET CD V].iso / enigma / earcd / sviluppo / svilupp2 / amphn192.lha / src / phonerexx.c < prev    next >
C/C++ Source or Header  |  1996-11-16  |  16KB  |  870 lines

  1. /*
  2.  * Source generated with ARexxBox 1.12 (May 18 1993)
  3.  * which is Copyright (c) 1992,1993 Michael Balzer
  4.  */
  5.  
  6. #include <exec/types.h>
  7. #include <exec/memory.h>
  8. #include <dos/dos.h>
  9. #include <rexx/storage.h>
  10. #include <rexx/rxslib.h>
  11.  
  12. #ifdef __GNUC__
  13. /* GCC needs all struct defs */
  14. #include <dos/exall.h>
  15. #include <graphics/graphint.h>
  16. #include <intuition/classes.h>
  17. #include <devices/keymap.h>
  18. #include <exec/semaphores.h>
  19. #endif
  20.  
  21. #include <clib/alib_protos.h>
  22. #include <clib/exec_protos.h>
  23. #include <clib/dos_protos.h>
  24. #include <clib/rexxsyslib_protos.h>
  25.  
  26. #ifndef __NO_PRAGMAS
  27.  
  28. #ifdef AZTEC_C
  29. #include <pragmas/exec_lib.h>
  30. #include <pragmas/dos_lib.h>
  31. #include <pragmas/rexxsyslib_lib.h>
  32. #endif
  33.  
  34. #ifdef LATTICE
  35. #include <pragmas/exec_pragmas.h>
  36. #include <pragmas/dos_pragmas.h>
  37. #include <pragmas/rexxsyslib_pragmas.h>
  38. #endif
  39.  
  40. #endif /* __NO_PRAGMAS */
  41.  
  42. #include <stdlib.h>
  43. #include <stdio.h>
  44. #include <string.h>
  45. #include <ctype.h>
  46.  
  47. #ifdef LATTICE
  48. #undef toupper
  49. #define inline __inline
  50. #endif
  51.  
  52. #ifdef __GNUC__
  53. #undef toupper
  54. static inline char toupper( char c )
  55. {
  56.     return( islower(c) ? c - 'a' + 'A' : c );
  57. }
  58. #endif
  59.  
  60. #define inline
  61.  
  62.  
  63. #include <dos/rdargs.h>
  64.  
  65. #include "phonerexx.h"
  66.  
  67. struct rxs_stemnode
  68. {
  69.     struct rxs_stemnode *succ;
  70.     char *name;
  71.     char *value;
  72. };
  73.  
  74.  
  75. extern struct ExecBase *SysBase;
  76. extern struct DosLibrary *DOSBase;
  77. extern struct RxsLib *RexxSysBase;
  78.  
  79. void (*ARexxResultHook)( struct RexxHost *, struct RexxMsg * ) = NULL;
  80.  
  81.  
  82.  
  83. void ReplyRexxCommand(
  84.     struct RexxMsg    *rexxmessage,
  85.     long            primary,
  86.     long            secondary,
  87.     char            *result )
  88. {
  89.     if( rexxmessage->rm_Action & RXFF_RESULT )
  90.     {
  91.         if( primary == 0 )
  92.         {
  93.             secondary = result
  94.                 ? (long) CreateArgstring( result, strlen(result) )
  95.                 : (long) NULL;
  96.         }
  97.         else
  98.         {
  99.             char buf[16];
  100.             
  101.             if( primary > 0 )
  102.             {
  103.                 sprintf( buf, "%ld", secondary );
  104.                 result = buf;
  105.             }
  106.             else
  107.             {
  108.                 primary = -primary;
  109.                 result = (char *) secondary;
  110.             }
  111.             
  112.             SetRexxVar( (struct Message *) rexxmessage,
  113.                 "RC2", result, strlen(result) );
  114.             
  115.             secondary = 0;
  116.         }
  117.     }
  118.     else if( primary < 0 )
  119.         primary = -primary;
  120.     
  121.     rexxmessage->rm_Result1 = primary;
  122.     rexxmessage->rm_Result2 = secondary;
  123.     ReplyMsg( (struct Message *) rexxmessage );
  124. }
  125.  
  126.  
  127. void FreeRexxCommand( struct RexxMsg *rexxmessage )
  128. {
  129.     if( !rexxmessage->rm_Result1 && rexxmessage->rm_Result2 )
  130.         DeleteArgstring( (char *) rexxmessage->rm_Result2 );
  131.  
  132.     if( rexxmessage->rm_Stdin &&
  133.         rexxmessage->rm_Stdin != Input() )
  134.         Close( rexxmessage->rm_Stdin );
  135.  
  136.     if( rexxmessage->rm_Stdout &&
  137.         rexxmessage->rm_Stdout != rexxmessage->rm_Stdin &&
  138.         rexxmessage->rm_Stdout != Output() )
  139.         Close( rexxmessage->rm_Stdout );
  140.  
  141.     DeleteArgstring( (char *) ARG0(rexxmessage) );
  142.     DeleteRexxMsg( rexxmessage );
  143. }
  144.  
  145.  
  146. struct RexxMsg *CreateRexxCommand( struct RexxHost *host, char *buff, BPTR fh )
  147. {
  148.     struct RexxMsg *rexx_command_message;
  149.  
  150.     if( (rexx_command_message = CreateRexxMsg( host->port,
  151.         rexx_extension, host->port->mp_Node.ln_Name)) == NULL )
  152.     {
  153.         return( NULL );
  154.     }
  155.  
  156.     if( (rexx_command_message->rm_Args[0] =
  157.         CreateArgstring(buff,strlen(buff))) == NULL )
  158.     {
  159.         DeleteRexxMsg(rexx_command_message);
  160.         return( NULL );
  161.     }
  162.  
  163.     rexx_command_message->rm_Action = RXCOMM | RXFF_RESULT;
  164.     rexx_command_message->rm_Stdin  = fh;
  165.     rexx_command_message->rm_Stdout = fh;
  166.     
  167.     return( rexx_command_message );
  168. }
  169.  
  170.  
  171. struct RexxMsg *CommandToRexx( struct RexxHost *host, struct RexxMsg *rexx_command_message )
  172. {
  173.     struct MsgPort *rexxport;
  174.     
  175.     Forbid();
  176.  
  177.     if( (rexxport = FindPort(RXSDIR)) == NULL )
  178.     {
  179.         Permit();
  180.         return( NULL );
  181.     }
  182.  
  183.     PutMsg( rexxport, &rexx_command_message->rm_Node );
  184.     
  185.     Permit();
  186.     
  187.     ++host->replies;
  188.     return( rexx_command_message );
  189. }
  190.  
  191.  
  192. struct RexxMsg *SendRexxCommand( struct RexxHost *host, char *buff, BPTR fh )
  193. {
  194.     struct RexxMsg *rcm;
  195.     
  196.     if( rcm = CreateRexxCommand(host, buff, fh) )
  197.         return CommandToRexx( host, rcm );
  198.     else
  199.         return NULL;
  200. }
  201.  
  202.  
  203. void CloseDownARexxHost( struct RexxHost *host )
  204. {
  205.     struct RexxMsg *rexxmsg;
  206.     
  207.     if( host->port )
  208.     {
  209.         /* Port abmelden */
  210.         RemPort( host->port );
  211.         
  212.         /* Auf noch ausstehende Replies warten */
  213.         while( host->replies > 0 )
  214.         {
  215.             WaitPort( host->port );
  216.             
  217.             while( rexxmsg = (struct RexxMsg *) GetMsg(host->port) )
  218.             {
  219.                 if( rexxmsg->rm_Node.mn_Node.ln_Type == NT_REPLYMSG )
  220.                 {
  221.                     if( !rexxmsg->rm_Args[15] )
  222.                     {
  223.                         /* Reply zu einem SendRexxCommand()-Call */
  224.                         if( ARexxResultHook )
  225.                             ARexxResultHook( host, rexxmsg );
  226.                     }
  227.                     
  228.                     FreeRexxCommand( rexxmsg );
  229.                     --host->replies;
  230.                 }
  231.                 else
  232.                     ReplyRexxCommand( rexxmsg, -20, (long) "Host closing down", NULL );
  233.             }
  234.         }
  235.         
  236.         /* MsgPort leeren */
  237.         while( rexxmsg = (struct RexxMsg *) GetMsg(host->port) )
  238.             ReplyRexxCommand( rexxmsg, -20, (long) "Host closing down", NULL );
  239.         
  240.         if( !(host->flags & ARB_HF_USRMSGPORT) )
  241.             DeleteMsgPort( host->port );
  242.     }
  243.     
  244.     if( host->rdargs ) FreeDosObject( DOS_RDARGS, host->rdargs );
  245.     FreeVec( host );
  246. }
  247.  
  248.  
  249. struct RexxHost *SetupARexxHost( char *basename, struct MsgPort *usrport )
  250. {
  251.     struct RexxHost *host;
  252.     int ext = 0;
  253.     
  254.     if( !basename )
  255.         basename = RexxPortBaseName;
  256.     else if( !*basename )
  257.         basename = RexxPortBaseName;
  258.     
  259.     if( !(host = AllocVec(sizeof *host, MEMF_CLEAR)) )
  260.         return NULL;
  261.     
  262.     strcpy( host->portname, basename );
  263.     
  264.     if( usrport )
  265.     {
  266.         host->port   = usrport;
  267.         host->flags |= ARB_HF_USRMSGPORT;
  268.     }
  269.     else if( !(host->port = CreateMsgPort()) )
  270.     {
  271.         FreeVec( host );
  272.         return NULL;
  273.     }
  274.     else
  275.     {
  276.         host->port->mp_Node.ln_Pri = 0;
  277.     }
  278.     
  279.     Forbid();
  280.     
  281.     while( FindPort(host->portname) )
  282.         sprintf( host->portname, "%s.%d", basename, ++ext );
  283.     
  284.     host->port->mp_Node.ln_Name = host->portname;
  285.     AddPort( host->port );
  286.     
  287.     Permit();
  288.     
  289.     if( !(host->rdargs = AllocDosObject(DOS_RDARGS, NULL)) )
  290.     {
  291.         RemPort( host->port );
  292.         if( !usrport ) DeleteMsgPort( host->port );
  293.         FreeVec( host );
  294.         return NULL;
  295.     }
  296.     
  297.     host->rdargs->RDA_Flags = RDAF_NOPROMPT;
  298.     
  299.     return( host );
  300. }
  301.  
  302.  
  303. /* StateMachine für FindRXCommand() */
  304.  
  305. static inline char *scmp( char *inp, char *str )
  306. {
  307.     while( *str && *inp )
  308.         if( *inp++ != *str++ )
  309.             return NULL;
  310.     
  311.     /* Reststring zurückgeben */
  312.     return inp;
  313. }
  314.  
  315. static int find( char *input )
  316. {
  317.     struct arb_p_state *st = arb_p_state;
  318.     struct arb_p_link *ad;
  319.     char *ni, tmp[36], *s;
  320.     
  321.     ni = tmp;
  322.     while( *input && ni-tmp < 32 )
  323.         *ni++ = toupper( *input++ );
  324.     *ni = 0;
  325.     input = tmp;
  326.     
  327.     while( *input )
  328.     {
  329.         /* Terminalzustand erreicht? */
  330.         if( !st->pa )
  331.         {
  332.             if( *input )
  333.                 return -1;
  334.             else
  335.                 return st->cmd;
  336.         }
  337.         
  338.         /* Wo geht's weiter? */
  339.         ni = 0;
  340.         for( ad = st->pa; s = ad->str; ad++ )
  341.         {
  342.             /* die Links sind absteigend sortiert */
  343.             if( *input > *s )
  344.                 break;
  345.             
  346.             if( *input == *s )
  347.                 if( ni = scmp(input+1, s+1) )
  348.                     break;
  349.         }
  350.         
  351.         /* Nirgends... */
  352.         if( !ni )
  353.             return -1;
  354.         
  355.         /* Zustandsüberführung */
  356.         st = arb_p_state + ad->dst;
  357.         input = ni;
  358.     }
  359.     
  360.     return st->cmd;
  361. }
  362.  
  363. struct rxs_command *FindRXCommand( char *com )
  364. {
  365.     int cmd;
  366.     
  367.     cmd = find( com );
  368.     
  369.     if( cmd == -1 )
  370.         return NULL;
  371.     else
  372.         return( rxs_commandlist + cmd );
  373. }
  374.  
  375.  
  376. static struct rxs_command *ParseRXCommand( char **arg )
  377. {
  378.     char com[256], *s, *t;
  379.     
  380.     s = *arg;
  381.     t = com;
  382.     
  383.     while( *s && *s != ' ' && *s != '\n' )
  384.         *t++ = *s++;
  385.     
  386.     *t = '\0';
  387.     while( *s == ' ' ) ++s;
  388.     *arg = s;
  389.     
  390.     return( FindRXCommand( com ) );
  391. }
  392.  
  393.  
  394. static char *CreateVAR( struct rxs_stemnode *stem )
  395. {
  396.     char *var;
  397.     struct rxs_stemnode *s;
  398.     long size = 0;
  399.     
  400.     if( !stem || stem == (struct rxs_stemnode *) -1L )
  401.         return( (char *) stem );
  402.     
  403.     for( s = stem; s; s = s->succ )
  404.         size += strlen( s->value ) + 1;
  405.     
  406.     if( !(var = AllocVec( size + 1, MEMF_ANY )) )
  407.         return( (char *) -1 );
  408.     
  409.     *var = '\0';
  410.     
  411.     for( s = stem; s; s = s->succ )
  412.     {
  413.         strcat( var, s->value );
  414.         if( s->succ )
  415.             strcat( var, " " );
  416.     }
  417.     
  418.     return( var );
  419. }
  420.  
  421.  
  422. static struct rxs_stemnode *new_stemnode( struct rxs_stemnode **first, struct rxs_stemnode **old )
  423. {
  424.     struct rxs_stemnode *new;
  425.     
  426.     if( !(new = AllocVec(sizeof(struct rxs_stemnode), MEMF_CLEAR)) )
  427.     {
  428.         return( NULL );
  429.     }
  430.     else
  431.     {
  432.         if( *old )
  433.         {
  434.             (*old)->succ = new;
  435.             (*old) = new;
  436.         }
  437.         else
  438.         {
  439.             *first = *old = new;
  440.         }
  441.     }
  442.     
  443.     return( new );
  444. }
  445.  
  446.  
  447. static void free_stemlist( struct rxs_stemnode *first )
  448. {
  449.     struct rxs_stemnode *next;
  450.     
  451.     if( (long) first == -1 )
  452.         return;
  453.     
  454.     for( ; first; first = next )
  455.     {
  456.         next = first->succ;
  457.         if( first->name  ) FreeVec( first->name );
  458.         if( first->value ) FreeVec( first->value );
  459.         FreeVec( first );
  460.     }
  461. }
  462.  
  463.  
  464. char *StrDup( char *s )
  465. {
  466.     char *t = AllocVec( strlen(s)+1, MEMF_ANY );
  467.     if( t ) strcpy( t, s );
  468.     return t;
  469. }
  470.  
  471.  
  472. static struct rxs_stemnode *CreateSTEM( struct rxs_command *rxc, LONG *resarray, char *stembase )
  473. {
  474.     struct rxs_stemnode *first = NULL, *old = NULL, *new;
  475.     char resb[512], *rs, *rb;
  476.     char longbuff[16];
  477.     
  478.     rb = resb;
  479.     if( stembase )
  480.     {
  481.         while( *stembase )
  482.             *rb++ = toupper( *stembase++ );
  483.     }
  484.     *rb = '\0';
  485.     
  486.     rb = resb + strlen(resb);
  487.     rs = rxc->results;
  488.     
  489.     while( *rs )
  490.     {
  491.         char *t = rb;
  492.         BOOL optn = FALSE, optm = FALSE;
  493.         
  494.         while( *rs && *rs != ',' )
  495.         {
  496.             if( *rs == '/' )
  497.             {
  498.                 ++rs;
  499.                 if( *rs == 'N' ) optn = TRUE;
  500.                 else if( *rs == 'M' ) optm = TRUE;
  501.             }
  502.             else
  503.                 *t++ = *rs;
  504.             
  505.             ++rs;
  506.         }
  507.         
  508.         if( *rs == ',' ) ++rs;
  509.         *t = '\0';
  510.         
  511.         /*
  512.          * Resultat(e) erzeugen
  513.          */
  514.         
  515.         if( !*resarray )
  516.         {
  517.             ++resarray;
  518.             continue;
  519.         }
  520.         
  521.         if( optm )
  522.         {
  523.             long *r, index = 0;
  524.             LONG **subarray = (LONG **) *resarray++;
  525.             struct rxs_stemnode *countnd;
  526.             
  527.             /* Anzahl der Elemente */
  528.             
  529.             if( !(new = new_stemnode(&first, &old)) )
  530.             {
  531.                 free_stemlist( first );
  532.                 return( (struct rxs_stemnode *) -1L );
  533.             }
  534.             countnd = new;
  535.             
  536.             /* Die Elemente selbst */
  537.             
  538.             while( r = *subarray++ )
  539.             {
  540.                 if( !(new = new_stemnode(&first, &old)) )
  541.                 {
  542.                     free_stemlist( first );
  543.                     return( (struct rxs_stemnode *) -1L );
  544.                 }
  545.                 
  546.                 sprintf( t, ".%ld", index++ );
  547.                 new->name = StrDup( resb );
  548.                 
  549.                 if( optn )
  550.                 {
  551.                     sprintf( longbuff, "%ld", *r );
  552.                     new->value = StrDup( longbuff );
  553.                 }
  554.                 else
  555.                 {
  556.                     new->value = StrDup( (char *) r );
  557.                 }
  558.             }
  559.             
  560.             /* Die Count-Node */
  561.             
  562.             strcpy( t, ".COUNT" );
  563.             countnd->name = StrDup( resb );
  564.             
  565.             sprintf( longbuff, "%ld", index );
  566.             countnd->value = StrDup( longbuff );
  567.         }
  568.         else
  569.         {
  570.             /* Neue Node anlegen */
  571.             if( !(new = new_stemnode(&first, &old)) )
  572.             {
  573.                 free_stemlist( first );
  574.                 return( (struct rxs_stemnode *) -1L );
  575.             }
  576.             
  577.             new->name = StrDup( resb );
  578.             
  579.             if( optn )
  580.             {
  581.                 sprintf( longbuff, "%ld", *((long *) *resarray) );
  582.                 new->value = StrDup( longbuff );
  583.                 ++resarray;
  584.             }
  585.             else
  586.             {
  587.                 new->value = StrDup( (char *) (*resarray++) );
  588.             }
  589.         }
  590.     }
  591.     
  592.     return( first );
  593. }
  594.  
  595.  
  596. static void DoRXCommand( struct RexxHost *host, struct RexxMsg *rexxmsg )
  597. {
  598.     struct rxs_command *rxc;
  599.     char *argb = NULL, *arg;
  600.     
  601.     LONG *array = NULL;
  602.     LONG *argarray;
  603.     LONG *resarray;
  604.     
  605.     char *cargstr = NULL;
  606.     long rc=20, rc2=0;
  607.     char *result = NULL;
  608.     
  609.     if( !(argb = AllocVec(strlen((char *) ARG0(rexxmsg)) + 2, MEMF_ANY)) )
  610.     {
  611.         rc2 = ERROR_NO_FREE_STORE;
  612.         goto drc_cleanup;
  613.     }
  614.     
  615.     /* welches Kommando? */
  616.     
  617.     strcpy( argb, (char *) ARG0(rexxmsg) );
  618.     strcat( argb, "\n" );
  619.     arg = argb;
  620.     
  621.     if( !( rxc = ParseRXCommand( &arg ) ) )
  622.     {
  623.         if( arg = ExpandRXCommand( host, (char *) ARG0(rexxmsg) ) )
  624.         {
  625.             FreeVec( argb );
  626.             if( !(argb = AllocVec( strlen(arg) + 2, MEMF_ANY )) )
  627.             {
  628.                 rc2 = ERROR_NO_FREE_STORE;
  629.                 goto drc_cleanup;
  630.             }
  631.             
  632.             strcpy( argb, arg );
  633.             strcat( argb, "\n" );
  634.             FreeVec( arg );
  635.             arg = argb;
  636.             
  637.             rxc = ParseRXCommand( &arg );
  638.         }
  639.     }
  640.     
  641.     if( !rxc )
  642.     {
  643.         /* Msg an ARexx schicken, vielleicht existiert ein Skript */
  644.         struct RexxMsg *rm;
  645.         
  646.         if( rm = CreateRexxCommand(host, (char *) ARG0(rexxmsg), NULL) )
  647.         {
  648.             /* Original-Msg merken */
  649.             rm->rm_Args[15] = (STRPTR) rexxmsg;
  650.             
  651.             if( CommandToRexx(host, rm) )
  652.             {
  653.                 /* Reply wird später vom Dispatcher gemacht */
  654.                 if( argb ) FreeVec( argb );
  655.                 return;
  656.             }
  657.             else
  658.                 rc2 = ERROR_NOT_IMPLEMENTED;
  659.         }
  660.         else
  661.             rc2 = ERROR_NO_FREE_STORE;
  662.         
  663.         goto drc_cleanup;
  664.     }
  665.     
  666.     if( !(rxc->flags & ARB_CF_ENABLED) )
  667.     {
  668.         rc = -10;
  669.         rc2 = (long) "Command disabled";
  670.         goto drc_cleanup;
  671.     }
  672.     
  673.     /* Speicher für Argumente etc. holen */
  674.     
  675.     (rxc->function)( host, (void **) &array, RXIF_INIT, rexxmsg );
  676.     cargstr = AllocVec( rxc->args ? 15+strlen(rxc->args) : 15, MEMF_ANY );
  677.     
  678.     if( !array || !cargstr )
  679.     {
  680.         rc2 = ERROR_NO_FREE_STORE;
  681.         goto drc_cleanup;
  682.     }
  683.     
  684.     argarray = array + 2;
  685.     resarray = array + rxc->resindex;
  686.     
  687.     /* Argumente parsen */
  688.     
  689.     if( rxc->results )
  690.         strcpy( cargstr, "VAR/K,STEM/K" );
  691.     else
  692.         *cargstr = '\0';
  693.     
  694.     if( rxc->args )
  695.     {
  696.         if( *cargstr )
  697.             strcat( cargstr, "," );
  698.         strcat( cargstr, rxc->args );
  699.     }
  700.     
  701.     if( *cargstr )
  702.     {
  703.         host->rdargs->RDA_Source.CS_Buffer = arg;
  704.         host->rdargs->RDA_Source.CS_Length = strlen(arg);
  705.         host->rdargs->RDA_Source.CS_CurChr = 0;
  706.         host->rdargs->RDA_DAList = NULL;
  707.         host->rdargs->RDA_Buffer = NULL;
  708.         
  709.         if( !ReadArgs(cargstr, argarray, host->rdargs) )
  710.         {
  711.             rc = 10;
  712.             rc2 = IoErr();
  713.             goto drc_cleanup;
  714.         }
  715.     }
  716.     
  717.     /* Funktion aufrufen */
  718.     
  719.     (rxc->function)( host, (void **) &array, RXIF_ACTION, rexxmsg );
  720.     
  721.     rc = array[0];
  722.     rc2 = array[1];
  723.     
  724.     /* Resultat(e) auswerten */
  725.     
  726.     if( rxc->results && rc==0 &&
  727.         (rexxmsg->rm_Action & RXFF_RESULT) )
  728.     {
  729.         struct rxs_stemnode *stem, *s;
  730.         
  731.         stem = CreateSTEM( rxc, resarray, (char *)argarray[1] );
  732.         result = CreateVAR( stem );
  733.         
  734.         if( result )
  735.         {
  736.             if( argarray[0] )
  737.             {
  738.                 /* VAR */
  739.                 if( (long) result == -1 )
  740.                 {
  741.                     rc = 20;
  742.                     rc2 = ERROR_NO_FREE_STORE;
  743.                 }
  744.                 else
  745.                 {
  746.                     char *rb;
  747.                     
  748.                     for( rb = (char *) argarray[0]; *rb; ++rb )
  749.                         *rb = toupper( *rb );
  750.                     
  751.                     if( SetRexxVar( (struct Message *) rexxmsg,
  752.                         *((char *)argarray[0]) ? (char *)argarray[0] : "RESULT",
  753.                         result, strlen(result) ) )
  754.                     {
  755.                         rc = -10;
  756.                         rc2 = (long) "Unable to set Rexx variable";
  757.                     }
  758.                     
  759.                     FreeVec( result );
  760.                 }
  761.                 
  762.                 result = NULL;
  763.             }
  764.             
  765.             if( !rc && argarray[1] )
  766.             {
  767.                 /* STEM */
  768.                 if( (long) stem == -1 )
  769.                 {
  770.                     rc = 20;
  771.                     rc2 = ERROR_NO_FREE_STORE;
  772.                 }
  773.                 else
  774.                 {
  775.                     for( s = stem; s; s = s->succ )
  776.                         rc |= SetRexxVar( (struct Message *) rexxmsg, s->name, s->value, strlen(s->value) );
  777.                     
  778.                     if( rc )
  779.                     {
  780.                         rc = -10;
  781.                         rc2 = (long) "Unable to set Rexx variable";
  782.                     }
  783.                     
  784.                     if( result && (long) result != -1 )
  785.                         FreeVec( result );
  786.                 }
  787.                 
  788.                 result = NULL;
  789.             }
  790.             
  791.             /* Normales Resultat: Möglich? */
  792.             
  793.             if( (long) result == -1 )
  794.             {
  795.                 /* Nein */
  796.                 rc = 20;
  797.                 rc2 = ERROR_NO_FREE_STORE;
  798.                 result = NULL;
  799.             }
  800.         }
  801.         
  802.         free_stemlist( stem );
  803.     }
  804.     
  805. drc_cleanup:
  806.  
  807.     /* Nur RESULT, wenn weder VAR noch STEM */
  808.     
  809.     ReplyRexxCommand( rexxmsg, rc, rc2, result );
  810.     
  811.     /* benutzten Speicher freigeben */
  812.     
  813.     if( result ) FreeVec( result );
  814.     FreeArgs( host->rdargs );
  815.     if( cargstr ) FreeVec( cargstr );
  816.     if( array ) (rxc->function)( host, (void **) &array, RXIF_FREE, rexxmsg );
  817.     if( argb ) FreeVec( argb );
  818. }
  819.  
  820.  
  821. void ARexxDispatch( struct RexxHost *host )
  822. {
  823.     struct RexxMsg *rexxmsg;
  824.  
  825.     while( rexxmsg = (struct RexxMsg *) GetMsg(host->port) )
  826.     {
  827.         if( (rexxmsg->rm_Action & RXCODEMASK) != RXCOMM )
  828.         {
  829.             /* Keine Rexx-Message */
  830.             ReplyMsg( (struct Message *) rexxmsg );
  831.         }
  832.         else if( rexxmsg->rm_Node.mn_Node.ln_Type == NT_REPLYMSG )
  833.         {
  834.             struct RexxMsg *org = (struct RexxMsg *) rexxmsg->rm_Args[15];
  835.             
  836.             if( org )
  837.             {
  838.                 /* Reply zu durchgereichter Msg */
  839.                 if( rexxmsg->rm_Result1 != 0 )
  840.                 {
  841.                     /* Befehl unbekannt */
  842.                     ReplyRexxCommand( org, 20, ERROR_NOT_IMPLEMENTED, NULL );
  843.                 }
  844.                 else
  845.                 {
  846.                     ReplyRexxCommand( org, 0, 0, (char *) rexxmsg->rm_Result2 );
  847.                 }
  848.             }
  849.             else
  850.             {
  851.                 /* Reply zu einem SendRexxCommand()-Call */
  852.                 if( ARexxResultHook )
  853.                     ARexxResultHook( host, rexxmsg );
  854.             }
  855.             
  856.             FreeRexxCommand( rexxmsg );
  857.             --host->replies;
  858.         }
  859.         else if( ARG0(rexxmsg) )
  860.         {
  861.             DoRXCommand( host, rexxmsg );
  862.         }
  863.         else
  864.         {
  865.             ReplyMsg( (struct Message *) rexxmsg );
  866.         }
  867.     }
  868. }
  869.  
  870.